﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Net;
using System.Web;

namespace ThreadEyePro
{
    public class KaskusConnection
    {
        public string userAgent = "BlackBerry8900/5.0.0.461 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/100";
        public bool isLoggedIn = false;
        public string pm = string.Empty;
        public bool hasNewPm = false;
        public CookieContainer cookies = null;
        public string userid = string.Empty;
        public string username = string.Empty;
        public string password = string.Empty;
        public string lastError = string.Empty;

        public KaskusConnection()
        {
            cookies = new CookieContainer();
        }

        public void login(string username, string password)
        {
            isLoggedIn = false;
            try
            {
                ServicePointManager.Expect100Continue = false;
                var r = (HttpWebRequest)WebRequest.Create("http://m.kaskus.us/user/login");
                r.CookieContainer = cookies;
                r.Method = "POST";
                r.AllowAutoRedirect = false;
                r.KeepAlive = true;
                r.Referer = "http://m.kaskus.us/";
                r.UserAgent = this.userAgent;
                r.ContentType = "application/x-www-form-urlencoded";

                using (var requestStream = r.GetRequestStream())
                {
                    using (var writer = new StreamWriter(requestStream))
                    {
                        writer.Write("username=" + HttpUtility.UrlEncode(username.Trim()) + "&password=" + HttpUtility.UrlEncode(password.Trim()) + "&login=Login");
                    }
                }
                HttpWebResponse webResponse = (HttpWebResponse)r.GetResponse();
                if (webResponse.Headers.Get("Location").Contains("loginsuccess"))
                {
                    isLoggedIn = true;
                }
                webResponse.Close();
            }
            catch (WebException e)
            {
                lastError = e.Message;
            }
            catch (Exception e)
            {
                lastError = e.Message;
            }
        }

        public string requestUrl(string url)
        {
            var result = string.Empty;
            
            try
            {
                ServicePointManager.Expect100Continue = false;
                var r = (HttpWebRequest)WebRequest.Create(url);
                r.CookieContainer = cookies;
                r.Method = "GET";
                r.AllowAutoRedirect = false;
                r.KeepAlive = true;
                r.Referer = "http://m.kaskus.us/";
                r.UserAgent = this.userAgent;

                using (var responseStream = r.GetResponse().GetResponseStream())
                {
                    using (var reader = new StreamReader(responseStream))
                    {
                        result = reader.ReadToEnd();
                    }
                }
            }
            catch (WebException e)
            {
                lastError = e.Message;
            }
            catch (Exception e)
            {
                lastError = e.Message;
            }

            if (result != "" && cookies.Count >= 1)
            {
                Match m = Regex.Match(result, "Welcome!([\\s]+)<a([\\s]+)href=\"http://m.kaskus.us/user/profile/([\\d]+)\">([^<]+)</a>", RegexOptions.Multiline);
                isLoggedIn = m.Success;
                if (m.Success)
                {
                    userid = m.Groups[3].Value.Trim();
                    username = m.Groups[4].Value.Trim();
                    // Count PM
                    m = Regex.Match(result, "inbox\">([^<]+)</a>", RegexOptions.Multiline);
                    if (m.Success)
                    {
                        pm = m.Groups[1].Value.Trim();

                        if (pm.ToLower() != "pm")
                        {
                            hasNewPm = true;
                        }
                        else
                        {
                            hasNewPm = false;
                        }
                    }
                }
            }
            return result;
        }

        public void postData(string url, string data)
        {
            string hash = requestPostHash(url);
            if (hash == string.Empty)
            {
                return;
            }
            data += "&hash=" + HttpUtility.UrlEncode(hash);

            try
            {
                ServicePointManager.Expect100Continue = false;
                var r = (HttpWebRequest)WebRequest.Create(url);
                r.CookieContainer = cookies;
                r.Method = "POST";
                r.AllowAutoRedirect = false;
                r.KeepAlive = true;
                r.Referer = "http://m.kaskus.us/";
                r.UserAgent = this.userAgent;
                r.ContentType = "application/x-www-form-urlencoded";

                using (var requestStream = r.GetRequestStream())
                {
                    using (var writer = new StreamWriter(requestStream))
                    {
                        writer.Write(data);
                    }
                }
                HttpWebResponse webResponse = (HttpWebResponse)r.GetResponse();
                // TODO : check for successfull here...
                webResponse.Close();
            }
            catch (WebException e)
            {
                lastError = e.Message;
            }
            catch (Exception e)
            {
                lastError = e.Message;
            }
        }

        public string requestPostHash(string url)
        {
            string hash = string.Empty;
            string webSrc = requestUrl(url);
            Match m = Regex.Match(webSrc, "name=\"hash\"([^>]+)>", RegexOptions.Multiline);
            if (m.Success)
            {
                Match h = Regex.Match(m.Groups[1].Value.Trim(), "value=\"([^\"]+)", RegexOptions.Multiline);
                if (h.Success)
                {
                    hash = h.Groups[1].Value.Trim();
                }
            }
            return hash;
        }

        public void newThread(string forumId, string title, string message)
        {
            string data = "";
            data += "title=" + HttpUtility.UrlEncode(title.Trim()) + "&";
            data += "message=" + HttpUtility.UrlEncode(message.Trim()) + "&";
            data += "reply=" + HttpUtility.UrlEncode("Submit") + "&";
            data += "forumid=" + forumId;
            postData("http://m.kaskus.us/newthread/" + forumId, data);
        }

        public void replyThread(KaskusThreadObject thread, string title, string message)
        {
            string data = "";
            data += "title=" + HttpUtility.UrlEncode(title.Trim()) + "&";
            data += "message=" + HttpUtility.UrlEncode(message.Trim()) + "&";
            data += "reply=" + HttpUtility.UrlEncode("Submit Reply") + "&";
            data += "threadid=" + thread.threadId.ToString();
            postData(thread.threadUrlReplyMobile, data);
        }

        public void sendPm(string recipients, string title, string message)
        {
            string data = "";
            data += "recipients=" + HttpUtility.UrlEncode(recipients.Trim()) + "&";
            data += "title=" + HttpUtility.UrlEncode(title.Trim()) + "&";
            data += "message=" + HttpUtility.UrlEncode(message.Trim()) + "&";
            data += "reply=Submit";
            postData("http://m.kaskus.us/newpm", data);
        }

        public KaskusThreadObject requestThread(KaskusThreadObject thread)
        {
            // Go to the latest possible page
            if (thread.pageCount > thread.pageNo)
            {
                thread.pageNo = thread.pageCount;
            }
            string webSrc = requestUrl(thread.threadUrlMobile);
            Match m;

            // Get the thread title
            m = Regex.Match(webSrc, "title>([^<]+)</title");
            if (m.Success)
            {
                string title = m.Groups[1].Value.Trim();
                Match x = Regex.Match(title, "(.*)- Kaskus - The Largest");
                if (x.Success)
                {
                    title = x.Groups[1].Value.Trim();
                }
                thread.threadTitle = title;
            }

            // Count posting
            thread.postCount = Regex.Matches(webSrc, "(<div class=\"poster\">)", RegexOptions.Multiline).Count;

            // Count page
            m = Regex.Match(webSrc, "(Page " + thread.pageNo.ToString() + " of ([\\d]+))", RegexOptions.Multiline);
            if (m.Success)
            {
                thread.pageCount = (int)Convert.ToInt32(m.Groups[2].Value.Trim());
            }

            webSrc = string.Empty;
            return thread;
        }
    }
}
